package com.cooper.mediadb.online;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.util.Log;

import com.cooper.scraper.DownloadException;
import com.cooper.scraper.HttpDownload;
import com.cooper.scraper.ScraperException;

public class AnalyzePPTV extends AnalyzeVideo {

	public AnalyzePPTV(HttpDownload httpDownload, String url, String format) {
		super(httpDownload, url, format);
	}

	private static final String VIDEO_ID_REG = "var\\s*webcfg\\s*=\\s*\\{\"id\":([^,]+),\"";
	private static final String FILE_LIST_REG = "<file[^>]*>((\\s|\\S)+?)</file>";
	//<item rid="%C3%A4%BE%AE.mp4" bitrate="296" vip="0" ft="0" width="480" height="272"/>
	private static final String FILE_ITEM_REG = "<item\\s+rid=\"([^\"]*)\"\\s+bitrate=\"(\\d+)\"\\s+vip=\"[^\"]*\"\\s+ft=\"(\\d+)\"[^>]*>";

	@Override
	public List<String> analyzeVideo() throws DownloadException,
			ScraperException, IOException {

		String page = httpDownload.downloadPage(url);

		if (!Thread.currentThread().isInterrupted()) {

			Matcher m = Pattern.compile(VIDEO_ID_REG).matcher(page);
			if (m.find()) {

				String detailsUrl = "http://web-play.pptv.com/webplay4-0-"
						+ m.group(1).trim() + ".xml&version=4&type=web.fpp";
				// http://web-play.pptv.com/webplay4-0-10117513.xml&version=4&type=web.fpp
				
				page = httpDownload.downloadPage(detailsUrl, false);
				if (!Thread.currentThread().isInterrupted()) {
					m = Pattern.compile(FILE_LIST_REG).matcher(page);
					if (m.find()) {
						String fileListStr = m.group(1);
						m = Pattern.compile(FILE_ITEM_REG).matcher(fileListStr);
						// SparseArray<PPTVVideoInfo> items = new
						// SparseArray<PPTVVideoInfo>();
						// Map<String, String> formatItems = new HashMap<String,
						// String>();
						List<PPTVVideoInfo> items = new ArrayList<PPTVVideoInfo>();
						while (m.find()) {
							PPTVVideoInfo info = new PPTVVideoInfo(
									Integer.parseInt(m.group(3)),
									Integer.parseInt(m.group(2)), m.group(1));
							items.add(info);

							// String format;

							// if (info.bitrate < 600) {
							// format = MediaSrcMgr.FORMAT_NORMAL;
							// } else if (info.bitrate < 900) {
							// format = MediaSrcMgr.FORMAT_REAL;
							// } else if (info.bitrate < 1100) {
							// format = MediaSrcMgr.FORMAT_HIGH;
							// } else {
							// format = MediaSrcMgr.FORMAT_SUPER;
							// }
							// items.put(info.ft, info);
							// formatItems.put(format, String.valueOf(info.ft));
						}

						Map<String, String> formatItems = new HashMap<String, String>();
						// confirm bitrate
						Log.d("AnalyzePPTV","");
						for (int i = 0; i < items.size(); i++) {
							String format;
							switch (i) {
							case 0:
								if ((items.size() == 1)
										&& (items.get(i).bitrate > 1100)) {
									format = MediaSrcMgr.FORMAT_SUPER;
								} else if ((items.size() == 1)
										&& (items.get(i).bitrate > 900)){
									format = MediaSrcMgr.FORMAT_HIGH;
								}else if ((items.size() == 1)
											&& (items.get(i).bitrate > 600)){
									format = MediaSrcMgr.FORMAT_REAL;
								}else
									format = MediaSrcMgr.FORMAT_NORMAL;
								break;
							case 1:
								if ((items.size() == 2)
										&& (items.get(i).bitrate > 1100)) {
									format = MediaSrcMgr.FORMAT_SUPER;
								}else if ((items.size() == 2)
										&& (items.get(i).bitrate > 900)){
									format = MediaSrcMgr.FORMAT_HIGH;
								} else
									format = MediaSrcMgr.FORMAT_REAL;
								break;
							case 2:
								if ((items.size() == 3)
										&& (items.get(i).bitrate > 1100)) {
									format = MediaSrcMgr.FORMAT_SUPER;
								} else
									format = MediaSrcMgr.FORMAT_HIGH;
								break;
							default:
								format = MediaSrcMgr.FORMAT_SUPER;
								if (i > 3) {
									Log.d("AnalyzePPTV", "format is out know:"
											+ i);
								}
								break;
							}
							formatItems.put(format, String.valueOf(i));
						}

						PPTVVideoInfo selectInfo = items.get(Integer
								.parseInt(getSelectFormatVideoId(formatItems)));
						m = Pattern.compile(
								"<dt\\s+ft=\"" + selectInfo.ft
										+ "\">((\\s|\\S)+?)</dt>")
								.matcher(page);
						if (m.find()) {
							if (selectInfo.setDt(m.group(1))) {
								m = Pattern
										.compile(
												"<dragdata(\\s|\\S)+?ft=\""
														+ selectInfo.ft
														+ "\">((\\s|\\S)+?)</dragdata>")
										.matcher(page);
								if (m.find()) {
									if (selectInfo.setSgm(m.group(2))) {
										return selectInfo.getUrls();
									}

								}
							}
						}

					}

				}

			}
		}
		return new ArrayList<String>();

	}

	private class PPTVVideoInfo {

		public int ft;

		public int bitrate;

		private String sh;

		//private String bh;

		private String key;

		private String rid;

		private List<Integer> sgms;

		public PPTVVideoInfo(int ft, int bitrate, String rid) {
			this.ft = ft;
			this.bitrate = bitrate;
			this.rid = rid;
		}

		public boolean setDt(String dt) {

			Matcher m = Pattern.compile("<sh>([^<]+)</sh>").matcher(dt);
			if (m.find()) {
				sh = m.group(1);
			} else {
				return false;
			}

			//m = Pattern.compile("<bh>([^<]+)</bh>").matcher(dt);
			//if (m.find()) {
			//	bh = m.group(1);
			//}

			m = Pattern.compile("<key[^>]*>([^<]+)</key>").matcher(dt);
			if (m.find()) {
				key = m.group(1);
			} else
				return false;

			return true;

		}

		public boolean setSgm(String sgm) {
			sgms = new ArrayList<Integer>();

			Matcher m = Pattern.compile("<sgm\\s+no=\"(\\d+)\"[^>]*>").matcher(
					sgm);
			while (m.find()) {
				sgms.add(Integer.parseInt(m.group(1)));
			}

			return !sgms.isEmpty();
		}

		// //
		// http://124.95.154.136/0/__B4__B9__D6__B1__BC__AB__CF__DE.mp4?k=28c25b69d62f0ff011b45cfa0dc21ca3-413b-1359036754
		public List<String> getUrls() {
			List<String> result = new ArrayList<String>();
			for (Integer sgm : sgms) {
				result.add("http://" + sh + "/" + sgm + "/"
						+ rid.replace("%", "__").trim() + "?k=" + key.trim());
			}

			return result;
		}

	}

}
